Remember that remote servers are supported in SQL
Server 2008 for backward compatibility only. (Remote servers are being
deprecated!) By definition, a remote server is a server you access as part of a client process without opening a separate, distinct, and additional direct
client connection. SQL Server can manage the communication between
servers using Remote Procedure Calls (RPCs). Essentially, the “local”
SQL Server to which the client is connected opens another connection to
the “remote” server and submits a remote stored procedure request to
the remote server. Execution results are passed back to the local
server, and they are then passed back to the originating client
application (see Figure 1).
You call a remote
procedure the same way you call a local procedure; the only difference
is that you need to fully qualify the name of the procedure with the
name of the server. This fully qualified procedure name includes the
server name node, database/catalog name node, database owner node, and
remote stored procedure name itself. The local SQL Server recognizes
this as a remote procedure, establishes the connection to the remote
server, and executes the stored procedure (remotely). Following is the
syntax for a fully qualified remote procedure call execution:
EXECUTE remote_server_name.db_name.owner_name.procedure_name
Here’s an example:
EXECUTE [DBARCH-LT2\SQL08DE02].[UnleashedRemoteDB].[dbo].[Top10Customers]
Remote servers are more limited
in functionality and a bit more time-consuming to set up than linked
servers. The following are the basic steps involved in setting up
remote servers:
1. | Define the local and remote servers on both servers.
|
2. | Configure each server for remote access.
|
3. | Create logins to be used with the remote servers.
|
4. | Create the login mappings from the local server to the remote server.
|
5. | Grant execute permissions for the remote login.
|
If you are connecting
between multiple SQL Server 2008, SQL Server 2005, SQL Server 2000, or
SQL Server 7.0 servers, it is best to set them up as linked servers and
not just remote
servers. However, if you need to execute Remote Procedure Calls only or
are on a pre-SQL Server 7.0 server, you need to set up remote servers
as described here.
Before we look at an example of a local server connecting to a remote
server, let’s first set up a database, create a sample table, and
create a stored procedure to execute on the remote server. The CustomersPlusSQLTable.sql script contains a create database statement that creates a database named UnleashedRemoteDB, creates a table named CustomersPlus
in this database, and populates the table with about 89 rows of test
data. You should go ahead and grab the script now and execute it on the
target remote server (SQL08DE02 in this example). You need to edit the create database statement (FILENAME
parameter) for your own environment. While you are executing this
script, go ahead and grab the three other scripts you will also need to
complete this remote server section: LocalServerSQL.sql, RemoteServerSQL.sql, and RPCexecution.sql.
Remote Server Setup
You can assume that the local server is called SQL08DE01 and the remote server is called SQL08DE02 (as shown in Figure 1). First, you need to use sp_addserver to add the remote server name to the system table in the master
database if it’s not defined already. But first, let’s see what servers
are already defined at the local server. To do so, you run sp_helpserver from the local server (SQL08DE01). This provides you with the complete list of local and remote servers known to this server:
EXECUTE sp_helpserver
go
name network_name status
id collation_name connect_timeout query_timeout
---------------- -------------- --------------------------------
-------------- --------------- -------------
DBARCH-LT2\SQL08DE01 DBARCH-LT2\SQL08DE01 rpc,rpc out,use
remote collation 0 NULL 0 0
You can also see the same information by doing a simple SELECT against the sys.servers system view:
SELECT * FROM sys.servers
Generally, you don’t need to execute sp_addserver for the local server. This is usually taken care of during SQL Server installation. The local server has an ID of 0. If you need to add the entry for the local server, you can specify the local flag as the second argument:
exec sp_addserver [DBARCH-LT2\SQL08DE01], local
You need to execute sp_addserver for each of the remote servers you will access from the local server. The SQL script LocalServerSQL.sql that you just got from the CD contains these commands. For example, on the local server (SQL08DE01), you execute the following command to add SQL08DE02:
EXECUTE sp_addserver [DBARCH-LT2\SQL08DE02]
Then, to see this new entry, you again execute sp_helpserver, as follows:
EXECUTE sp_helpserver
go
name network_name status
id collation_name connect_timeout query_timeout
---------------- -------------- --------------------------------
-------------- --------------- -------------
DBARCH-LT2\SQL08DE01 DBARCH-LT2\SQL08DE01 rpc,rpc out,use
remote collation 0 NULL 0 0
DBARCH-LT2\SQL08DE02 DBARCH-LT2\SQL08DE02 rpc,rpc out,use
remote collation 1 NULL 0 0
You now see the newly added remote server entry (with an ID of 1 in this example).
To drop a remote server entry, you need to execute sp_dropserver. For example, on the local server (SQL08DE01), you execute the following command to drop the SQL08DE02 remote server entry:
EXECUTE sp_dropserver [DBARCH-LT2\SQL08DE02]
If the local server is a 7.0 or later version of SQL Server, you can add the remote servers by using sp_addlinkedserver:
EXECUTE sp_addlinkedserver [DBARCH-LT2\SQL08DE02]
This command sets up
the server for remote stored procedure execution and for direct data
access.
Now, on the remote server ([DBARCH-LT2\SQL08DE02]), you need to define the local server ([DBARCH-LT2\SQL08DE01]) that will be connecting to it. The SQL script RemoteServerSQL.sql that you just got from the CD contains these commands:
EXECUTE sp_addserver [DBARCH-LT2\SQL08DE01]
You also need to verify that
each server (both the local and remote servers) allows remote
connections. This is the SQL Server 2008 default but can easily be
verified by looking at the properties for each server from SQL Server
Management Studio. By default, remote access is automatically enabled
during setup to support replication. Figure 2
shows the current configured values of the remote server connection
entry, indicating that remote connections to this server are allowed
(checked) for the DBARCH-LT2\SQL08DE02 remote SQL Server. You need to double-check both servers (local and remote).
You can also configure this remote connection access by using sp_configure. The proper syntax is as follows:
EXECUTE sp_configure 'remote access', 1
reconfigure
After enabling remote access, you need to shut down and restart each server.
Now you need to follow the
basic rule of allowing only a named SQL login the capability to execute
a remote stored procedure. In this way, you can tightly control the
permissions and execution of that stored procedure from wherever the
remote execution request originates from. You start by creating the
logins you want to use to connect to the local SQL Server (SQL08DE01 in this example) and the same login name on the remote SQL Server (SQL08DE02
in this example). You can do this by using Microsoft SQL Server
Management Studio (new login) or by using a CREATE LOGIN SQL command,
as follows (on the local server, which is SQL08DE01 in this example):
-- FROM THE LOCAL SERVER ONLY--
CREATE LOGIN ForRPC WITH PASSWORD = 'password',
CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF,
DEFAULT_DATABASE = master
go
This SQL Server login will
connect from the client application. Note that your environment might
want to enforce various password policies, conventions, and expiration
dates.
Next, you create the corresponding SQL login on the remote server (and
make that login a user in the database where the remote procedure is
located). Again, this can be done by using Microsoft SQL Server
Management Studio (new login) on the remote server (SQL08DE02 in this example) or by using the CREATE LOGIN and CREATE USER SQL commands as follows:
--- FROM THE REMOTE SERVER ONLY --
CREATE LOGIN ForRPC WITH PASSWORD = 'password',
CHECK_EXPIRATION = OFF, CHECK_POLICY = OFF,
DEFAULT_DATABASE = UnleashedRemoteDB
go
USE [UnleashedRemoteDB]
GO
CREATE USER [ForRPC] FOR LOGIN [ForRPC]
GO
Notice
that you also identify the default database for this remote login to be
the database created earlier in this example (UnleashedRemoteDB test database). You also make the login a user within that database.
Now you must set up login
mappings on the remote server and possibly on the local server.
Basically, remote server login mappings must be set up on the remote
server to map the incoming login for an RPC connection from a specified
server to a local login (on the remote server). In other words, you
need to define how to map the logins from the server making the remote
procedure request (SQL08DE01) to the environment on the server receiving the request (SQL08DE02). Also, the trusted option of sp_remoteoption
is not supported in SQL Server 2005 or SQL Server 2008. This change was
made to close a huge security hole in prior SQL Server versions.
Although you are technically setting things up on the remote server (SQL08DE02),
when you are doing things on the remote server, it is typically
referred to as the local server, and the local server (SQL08DE01)
is treated as the remote server. It’s easiest to think about this
situation from the point of view of where you are standing (at the
local server versus the remote server). Then it will make a lot more
sense.
Following is the syntax for the sp_addremotelogin command:
EXECUTE sp_addremotelogin remote_server_name
[, local_login_name [, remote_login_name]]
For example, on the remote server (SQL08DE02), you execute the following command to map the newly created login on SQL08DE01 to the same login on SQL08DE02:
EXECUTE sp_addremotelogin [DBARCH-LT2\SQL08DE01], ForRPC, ForRPC
This is the simplest
mapping method. It presumes that the logins are the same on both
servers, and it maps login to login. To see the complete list of
resulting mappings, you simply execute sp_helpremotelogin:
EXECUTE sp_helpremotelogin
go
server local_user_name remote_user_name options
---------------------- ---------------------- ---------------- -------
DBARCH-LT2\SQL08DE01 ForRPC ForRPC
Tip
If users from the remote server need access on your server, don’t forget to add them with the CREATE LOGIN statement first.
The login to which you map
the remote logins determines the permissions the remote users will have
on the local server. If you want to restrict the procedures that the
remote users can execute, you need to be sure to set the appropriate
permissions on the procedure for the login to which they are mapping.
To set execute permissions for the RPC named Top10Customers to the SQL login of ForRPC, you use the following:
GRANT EXECUTE ON [UnleashedRemoteDB].[dbo].[Top10Customers] TO ForRPC
go
That’s it! You are now
ready to execute an RPC via the local server as soon as you connect to
the local server with the just-created ForRPC SQL login credentials. The SQL script name RPCexecution.sql contains the remote stored procedure execution statement. You simply log in to the local server (SQL08DE01 in this example) using the ForRPC SQL login and execute the fully qualified remote stored procedure as follows:
-- FROM LOCAL SERVER – SQL08DE01 in our example --
use [master]
go
EXECUTE [DBARCH-LT2\SQL08DE02].[UnleashedRemoteDB].[dbo].[Top10Customers]
go
CustomerID CompanyName City Country YTDBusiness
---------- --------------------- ----- ------- -----------
BERTU Bertucci Villa Milano Italy 200039.80
QUICK QUICK-Stop Cunewalde Germany 117483.39
SAVEA Save-a-lot Markets Boise USA 115673.39
ERNSH Ernst Handel Graz Austria 113236.68
HUNGO Hungry Owl All-Night Cork Ireland 57317.39
RATTC Rattlesnake Canyon Albuquerque USA 52245.90
HANAR Yves Moison Paris France 34101.15
FOLKO Folk och fä HB Bräcke Sweden 32555.55
MEREP Thierry Gerardin Vannes France 32203.90
KOENE Königlich Essen Brandenburg Germany 31745.75
(10 row(s) affected)
As
you can see, setting up remote servers can be a bit confusing and a
tedious process. You have to perform setup tasks on both the local and
remote servers. In addition, the mapping of logins severely limits what
types of servers can be accessed. Login mappings are performed at the
remote server instead of the local server, which works fine if the
remote server is a SQL Server machine, but how do you perform this task
in another database environment that doesn’t have user mappings? How do
you tell an Oracle database to which Oracle user to map a SQL Server
user? When you understand how linked servers are set up and what
expanded capabilities they provide, you won’t want to use remote
servers unless you absolutely have to, which should be only when you
need to execute RPCs on pre-7.0 SQL Servers.